import { ref, onMounted, onUnmounted } from 'vue'

export function useInfiniteScroll(
    loadMore: () => Promise<void>,
    options: {
        threshold?: number
        rootMargin?: string
        disabled?: () => boolean
    } = {}
) {
    const loading = ref(false)
    const finished = ref(false)
    const error = ref<string | null>(null)
    const containerRef = ref<HTMLElement>()

    const { threshold = 100, disabled } = options

    const handleScroll = async () => {
        if (loading.value || finished.value || (disabled && disabled())) {
            return
        }

        const container = containerRef.value
        if (!container) return

        const { scrollTop, scrollHeight, clientHeight } = container
        const distanceToBottom = scrollHeight - scrollTop - clientHeight

        if (distanceToBottom <= threshold) {
            try {
                loading.value = true
                error.value = null
                await loadMore()
            } catch (err) {
                error.value = err instanceof Error ? err.message : 'Loading failed'
            } finally {
                loading.value = false
            }
        }
    }

    const reset = () => {
        finished.value = false
        error.value = null
        loading.value = false
    }

    const setFinished = () => {
        finished.value = true
    }

    onMounted(() => {
        const container = containerRef.value || window
        container.addEventListener('scroll', handleScroll, { passive: true })
    })

    onUnmounted(() => {
        const container = containerRef.value || window
        container.removeEventListener('scroll', handleScroll)
    })

    return {
        loading,
        finished,
        error,
        containerRef,
        reset,
        setFinished
    }
}